#wxSurvivalEntry
#Base class for entering survival probabilities on a per species basis in a grid
#Provides a wxgrid and a wxlinegraph 
#The grid contains the species and a column for selecting which species to plot
#It is assumed that the derived class utilises this grid to update the survival 
#object which is then plotted by this class.  

use Wx 0.15 qw[:allclasses];
use strict;
package wxSurvivalEntry;

#use wxGridLessScroll;
use Wx qw[:everything];
use base qw(Wx::SplitterWindow);
use strict;
use Storable;
use Scalar::Util qw(blessed);
use wxLineGraph;

sub new {
	my $self = shift;
	
	#Create the panel
	print $self;
	$self = $self->SUPER::new( @_ );

	#Create the splitter
	#$self->{window_splitter} = Wx::SplitterWindow->new($self, -1, wxDefaultPosition, wxDefaultSize, wxSP_3D|wxSP_BORDER);
	$self->{panel_grid} = Wx::Panel->new($self, -1, wxDefaultPosition, wxDefaultSize);
	$self->{panel_graph} = wxLineGraph->new($self, -1);

	#Create the grid
	$self->{grid} = Wx::Grid->new($self->{panel_grid}, -1, wxDefaultPosition, wxDefaultSize,wxSP_3D|wxSP_BORDER);
	
	$self->{grid}->CreateGrid(0,0);

	#We set the default b/g colour to gray so that the area outside the grid is not drawn white
	#on some platforms this overwrites the grid line colour so we store and reset this here
	my $gl_colour = $self->{grid}->GetGridLineColour(); 
   	$self->{grid}->SetDefaultCellBackgroundColour(Wx::SystemSettings::GetSystemColour(wxSYS_COLOUR_3DFACE));	
	$self->{grid}->SetGridLineColour($gl_colour);
	
	#Do the layout
	$self->{sizer} = Wx::BoxSizer->new(wxVERTICAL);
	$self->{sizer_h} = Wx::BoxSizer->new(wxHORIZONTAL);
	$self->{sizer}->Add($self->{sizer_h}, 1, wxEXPAND);	
	$self->{sizer_h}->Add($self->{grid}, 1, wxEXPAND | wxCENTER);
	$self->{sizer_h}->AddStretchSpacer(0);
#	$self->{sizer}->Add($self->{grid}, 1, wxEXPAND | wxCENTER);

	$self->{panel_grid}->SetSizer($self->{sizer});

	$self->Initialize($self->{panel_grid});	
	$self->Layout();
	$self->SplitVertically($self->{panel_grid}, $self->{panel_graph}, 300);
	$self->initialise_plot_colours();
	Wx::Event::EVT_GRID_CELL_LEFT_CLICK($self, \&toggle_value);
	#Wx::Event::EVT_GRID_CELL_CHANGE($self, \&test);
	Wx::Event::EVT_GRID_COL_SIZE($self, \&set_max_size);
	Wx::Event::EVT_GRID_ROW_SIZE($self, \&set_max_size);

	$self->{grid}->DisableDragRowSize();
	$self->set_max_size();
	return $self;
}

sub set_max_size {
	my ($self, $event) = @_;
 	if (defined $event) { $event->Skip(); }
 	return;
	my $x = $self->{grid}->GetRowLabelSize();
	my $y = $self->{grid}->GetColLabelSize();
	print ":$x,$y\n";
	for (my $index = 0; $index < $self->{grid}->GetNumberCols(); $index++ ) {
		$x += $self->{grid}->GetColSize($index);
	}
	for (my $index = 0; $index < $self->{grid}->GetNumberRows(); $index++ ) {
		$y += $self->{grid}->GetRowSize($index);
	}
	
	$self->{grid}->SetMargins(0,0);
	$self->{grid}->SetMaxSize(Wx::Size->new($x+9,$y+9));
	print "::$x,$y\n";
	my ($x2, $y2) = $self->{grid}->GetVirtualSize();
	print ":::$x2,$y2\n";
	
#	$self->{grid}->Fit();
	$self->{panel_grid}->Layout();
	$self->{grid}->Refresh();
	 ($x2, $y2) = $self->{grid}->GetVirtualSize();
	print ":::$x2,$y2\n";
	
	$self->{grid}->SetColLabelSize($self->{grid}->GetColLabelSize());
	
}

#Sets colours for plotting
sub initialise_plot_colours {
	my $self = shift;
	#Some colours, could do better!
	my @red   = (255,   0,   0, 255, 255, 255, 255,   0, 192,   0,   0, 192, 192, 192, 192,   0, 128,   0,   0, 128, 128, 128, 128,   0);
	my @green = (  0, 255,   0, 255,   0,   0, 255, 255,   0, 192,   0, 192,   0,   0, 192, 192,   0, 128,   0, 128,   0,   0, 128, 128);
	my @blue  = (  0,   0, 255,   0, 255, 255,   0, 255,   0,  0,  192,   0, 192, 192,   0, 192,   0,  0,  128,   0, 128, 128,   0, 128);
	
	for (my $index = 0; $index < @red; $index++) {
		push (@{$self->{colours}}, Wx::Colour->new($red[$index], $green[$index], $blue[$index]));
		$self->{'Avail'.$red[$index].'.'.$green[$index].'.'.$blue[$index]} = 1; 
	}
}

sub checkout_colour {
	my $self = shift;
	foreach (@{$self->{colours}}) {
		if ($self->{'Avail'.$_->Red().'.'.$_->Green().'.'.$_->Blue()}) {
			$self->{'Avail'.$_->Red().'.'.$_->Green().'.'.$_->Blue()} = 0;
			return $_;
		} 
	}
	
	return wxBLACK;
}

sub return_colour {
	my $self = shift;
	my $colour = shift;
	$self->{'Avail'.$colour->Red().'.'.$colour->Green().'.'.$colour->Blue()} = 1;
}

#Toggle the bool value (less clicking by avoiding the editor - although can't use keyboard yet...)
sub toggle_value {
	my ($self, $event) = @_;
	my $row = $event->GetRow();
	my $col = $event->GetCol();
	
	my $text_colour;
	
	if ($self->is_bool($row,$col)) {
		if ($self->{grid}->GetCellValue($row,$col)) {
			$self->{grid}->SetCellValue($row,$col,'0');
		} else {
			$self->{grid}->SetCellValue($row,$col,'1');
		}
		$self->update_plot_selection();
		$self->plot_survival();
	}	
	$event->Skip();
}

#Updates the colours and selection from the plot column
sub update_plot_selection {
	my $self = shift;

	my $col = $self->{grid}->GetNumberCols()-1;

	for (my $row = 0; $row < $self->{grid}->GetNumberRows(); $row++) {
		my $species = $self->{grid}->GetRowLabelValue($row);
		my $text_colour = undef;
		if ($self->{grid}->GetCellValue($row,$col) && !defined $self->{row_colour}->{$species}) {
			$text_colour = $self->checkout_colour();
			$self->{row_colour}->{$species} = $text_colour;
		} elsif (!$self->{grid}->GetCellValue($row,$col) && defined $self->{row_colour}->{$species}) {
			$text_colour = wxBLACK;
			$self->return_colour($self->{grid}->GetCellTextColour($row,$col));
			delete $self->{row_colour}->{$species};
		}
		if (defined $text_colour) { $self->{grid}->SetCellTextColour($row,$col,$text_colour);}
	}
}

#Set the state
sub set_state {
	my $self = shift;
	$self->{state} = shift;
}

#Plot the survival figure
sub plot_survival {
	my $self = shift;
	$self->{panel_graph}->delay_plotting();
	$self->{panel_graph}->clear();
	
	#Plot each line
	foreach (keys %{$self->{row_colour}}) {
		#Get the data points
		my @cost = $self->{state}->{survival}->get_species_cost($_);
		my @prob = $self->{state}->{survival}->get_species_probability($_);
		#Get the colour
		my $options_hash = {'colour'=>$self->{row_colour}->{$_}};
		#Add the line to the plot list
		$self->{panel_graph}->add_line(\@cost,\@prob,$options_hash);
	}
	$self->{panel_graph}->resume_plotting();	
}

#Adds species row labels and plot column
sub blank_grid {
	my $self = shift;

	#Delete all rows and cols
	$self->{grid}->DeleteRows(0, $self->{grid}->GetNumberRows);
	$self->{grid}->DeleteCols(0, $self->{grid}->GetNumberCols);
	
	delete $self->{renderers};
	
	unless (defined $self->{state}->{species}) { return; }
	my @species = sort @{$self->{state}->{species}};
	
	#Add the right number of rows and cols
	$self->{grid}->AppendRows(scalar @species);
	$self->{grid}->AppendCols(1);
	for (my $index = 0; $index < $self->{grid}->GetNumberRows(); $index++) {
		$self->{grid}->SetCellBackgroundColour($index, 0, wxWHITE);
	}
	
	#Enter species names and create check boxes
	for (my $index = 0; $index < @species; $index++) {
		$self->{grid}->SetRowLabelValue($index, $species[$index]);
		$self->make_cell_bool($index,0);
	}
	$self->{grid}->SetColLabelValue(0, 'Plot');
	$self->{grid}->AutoSizeColumn(0);
	$self->Layout();
}

#Make a cell a boolean
sub make_cell_bool {
	my ($self, $row, $col, $value) = @_;
	if (defined $value && $value) {
		$self->{grid}->SetCellValue($row, $col, '1');
	} else {
		$self->{grid}->SetCellValue($row, $col, '0');
	}
	$self->{grid}->SetCellRenderer($row, $col, Wx::GridCellBoolRenderer->new());
    $self->{grid}->SetReadOnly($row,$col);
    $self->{grid}->SetCellAlignment($row,$col, wxALIGN_CENTRE, wxALIGN_CENTRE);
	
}

#Insert a column on left, shifting the column labels across (not done automatically by wxWidgets)
#argument is column label and optionally the index of the insertion point
sub insert_col {
	my $self = shift;
	my $label = shift;
	my $insertion = shift;
	unless (defined $insertion) { $insertion = 0; }
	
	#Store old col label values (used to just shift them over but wx 2.6 and 2.8 have some strange differences
	#this ends up being foolproof
	my @col_labels;
	for (my $index = 0; $index < $self->{grid}->GetNumberCols(); $index++) {
		if ($index == $insertion) { push(@col_labels, $label); }
		push(@col_labels, $self->{grid}->GetColLabelValue($index));
	}
	$self->{grid}->InsertCols($insertion,1,0);
	
	#Relabel columns
	for (my $index = 0; $index < $self->{grid}->GetNumberCols(); $index++) {
		$self->{grid}->SetColLabelValue($index, $col_labels[$index]); 
	}
	

	#Set background colour of all new cells	
	for (my $index = 0; $index < $self->{grid}->GetNumberRows(); $index++) {
		$self->{grid}->SetCellBackgroundColour($index, $insertion, wxWHITE);
	}

	$self->{grid}->SetColLabelValue($insertion, $label);
	$self->{grid}->AutoSizeColumn($insertion);
	$self->Layout();
	
}

#Insert a row on the top, shifting the row labels down (not done automatically by wxWidgets)
#argument is row label
sub insert_row {
	my $self = shift;
	
	$self->{grid}->InsertRows(0,1,0);
	for (my $index = $self->{grid}->GetNumberRows()-1; $index > 0; $index--) {
		$self->{grid}->SetRowLabelValue($index, $self->{grid}->GetRowLabelValue($index-1));
	}
	for (my $index = 0; $index < $self->{grid}->GetNumberCols(); $index++) {
		$self->{grid}->SetCellBackgroundColour(0, $index, wxWHITE);
	}
	$self->{grid}->SetRowLabelValue(0, shift);
	$self->{grid}->SetRowLabelSize(120);
	$self->Layout();
	
}

#Enable a single cell (input is row, col, bool)
sub enable_cell {
	my ($self, $row, $col, $bool) = @_;

	$self->{grid}->SetReadOnly($row,$col,!$bool);
	if ($bool) {
		$self->{grid}->SetCellBackgroundColour($row,$col, wxWHITE);
	} else {
		$self->{grid}->SetCellBackgroundColour($row,$col, wxLIGHT_GREY);
	}
	
}

#Update the GUI (spp have changed) 
sub update {
	my $self = shift;
	$self->blank_grid();
	$self->fill_grid();
}	

sub fill_grid {
	
}
sub _get_pointer_address {
	my $pointer = shift;
	my ($output) = ($pointer =~ /[^\(]+\(([0-9a-fx]+)\)/);
	return $output;
}

1;